#include <iostream>

using std::cout;
using std::endl;

struct B {
    virtual void vf(int n) {
        cout << "calling B::vf(" << n << ")..." << endl;
        cout << "\ta: " << a << endl;
    }
    void f(int n) {}
    int a = 1;
};

struct D : B {
    void vf(int n) {
        cout << "calling D::vf(" << n << ")..." << endl;
        cout << "\ta: " << a << endl;
    }
    virtual void vf2(int n) {}
    int a = 2;
};

typedef void F1(int); 
typedef void BMF1(B&, int);
typedef void BMF2(B*, int);

int main() {
    B b;
    D d;
    //桩函数，根据第一个参数(实例指针借助虚函数标指针)找到对应的虚函数并调用
    F1 B::*vfp1 = &B::vf; 
    F1 D::*vfp2 = &D::vf;
    F1 D::*vfp =  &D::vf2;
    F1 D::*fp =  &B::f;
    B *bp = &d;
    
    //cout << "fp(&B::f): " << fp << endl; //error: cout输出异常
    //cout << "&B::vf: "  << &B::vf << endl; //error
    //cout << "&D::vf: " << &D::vf << endl; //error
    //cout << "vfp1(&B::vf): " << vfp1 << endl; //error
    //cout << "vfp2(&D::vf): " << vfp2 << endl; //error
    //cout << "vfp(&D::vf2): " << vfp << endl; //error

    cout << "(void*)fp(&B::f): " << (void*)fp << endl; //函数地址
    cout << "(void*)&B::vf: "  << (void*)&B::vf << endl; //虚函数地址
    cout << "(void*)&D::vf: " << (void*)&D::vf << endl; //虚函数地址
    cout << "(void*)vfp1(&B::vf): " << (void*)vfp1 << endl; //虚函数偏移
    cout << "(void*)vfp2(&D::vf): " << (void*)vfp2 << endl; //虚函数偏移
    cout << "(void*)vfp(&D::vf2): " << (void*)vfp << endl; //虚函数偏移

    //cout << "fp(&B::f): " << (F1*)fp << endl; //error
    //cout << "(F1*)&B::vf: "  << (F1*)&B::vf << endl; //error
    //cout << "(F1*)&D::vf: " << (F1*)&D::vf << endl; //error
    //cout << "(F1*)vfp1(&B::vf): " << (F1*)vfp1 << endl; //error
    //cout << "(F1*)vfp2(&D::vf): " << (F1*)vfp2 << endl; //error
    //cout << "vfp(&D::vf2): " << (F1*)vfp << endl; //error

    cout << "(void*)vfp1(&B::vf) == (void*)vfp2(&D::vf): " << 
            ((void*)vfp1 == (void*)vfp2 ?"true": "false") << endl;
    cout << "(void*)&B::vf == (void*)&D::vf: " << ((void*)&B::vf == (void*)&D::vf ?"true": "false") << endl;
    cout << "(F1*)&B::vf == (F1*)&D::vf: " << ((F1*)&B::vf == (F1*)&D::vf ?"true": "false") << endl;

    (b.*vfp1)(1);
    // (b.*vfp2)(); //error can not base to derive

    (d.*vfp1)(2); //多态
    (d.*vfp2)(3);

    (bp->*vfp1)(4); //多态
    //(bp->*vfp2)(); //error can not base to derive
    

    ((BMF1*)&B::vf)(d, 5); //B::vf, 无多态
    ((BMF2*)&D::vf)(&d, 6); //D::vf2
    
    //((BMF1*)vfp1)(b, 7); //error, 虚成员函数指针类型实际为函数偏移
    //((BMF2*)vfp2)(&d, 8); //error, 虚成员函数指针类型实际为函数偏移

    return 0;
}
